//引入相应请求函数:登录请求函数、退出登录请求函数、获取用户信心请求函数
import { login, logout, getInfo } from "@/api/acl/user";
//cookie持久存储token封装好的函数
import { getToken, setToken, removeToken } from "@/utils/auth";
import { resetRouter } from "@/router";

// 深拷贝
import cloneDeep from "lodash/cloneDeep";

import router from "@/router";
// 获取常量路由、异步路由、任意路由
//常量路由不用计算、任意路由、异步路由需要计算
import { constantRoutes, asyncRoutes, ryRoute } from "@/router";

const getDefaultState = () => {
  return {
    // 令牌：登陆成功服务器会返回token
    token: getToken(),
    // 用户的名字
    name: "",
    // 用户的头像
    avatar: "",
    // 职位
    roles: [],
    // 按钮标记
    buttons: [],
    // 异步路由的标记
    routes: [],
    //不同用户将来计算完毕的全部的路由
    userAllRoutes: [],
  };
};
//小仓库存储数据的地方
const state = getDefaultState();

//定义函数:计算出当前用户异步路由的结果
const findUserAsyncRoute = (asyncRoutes, flagArr) => {
  //通过递归计算出用户异步路由[包含一级路由，二级路由]
  let result = asyncRoutes.filter((item) => {
    if (flagArr.includes(item.name)) {
      //递归判断:如果一级路由还有二级、三级、四级..子路由接着判断
      if (item.children && item.children.length > 0) {
        item.children = findUserAsyncRoute(item.children, flagArr);
      }
      return true;
    }
  });
  return result;
};

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState());
  },
  //存储token
  SET_TOKEN: (state, token) => {
    state.token = token;
  },
  // 存储用户全部的信息
  SET_USERINFO: (state, data) => {
    //vuex存储用名字
    state.name = data.name;
    //vuex存储头衔
    state.avatar = data.avatar;
    //vue存储用户职位
    state.roles = data.roles;
    //vuex存储按钮标记
    state.buttons = data.buttons;
    //vuex存储的是异步路由标记
    state.routes = data.routes;
  },
  //不同用户最终计算出来的全部路由
  SET_USERALLROUTES: (state, ybRoute) => {
    //vuex存储当前用户全部的路由信息
    //将常量路由 + 计算出来异步路由 + 任意路由,不就是当前用户全部的路由！！！
    state.userAllRoutes = constantRoutes.concat(ybRoute, ryRoute);
    //vue-router最开始的时候，仅仅注册的是常量路由
    //router.addRoutes动态追加其余路由【异步路由，任意路由】
    router.addRoutes([...ybRoute, ryRoute]);
  },
};

const actions = {
  // 登录的action：发请求+用户名+密码
  async login({ commit }, userInfo) {
    // 解构用户信息
    const { username, password } = userInfo;
    // 登录请求
    let result = await login({ username: username.trim(), password: password });
    // console.log(result);
    if (result.code === 20000) {
      // vuex仓库存储一份token，并非持久化
      commit("SET_TOKEN", result.data.token);
      // 本地存储持久化存储token{cookie}
      setToken(result.data.token);
      return "ok";
    } else {
      return Promise.reject(new Error());
    }
  },

  // 获取用户信息的方法
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      // 携带token获取用户信息
      getInfo(state.token)
        .then((response) => {
          // response是服务器返回用户信息
          const { data } = response;
          // 存储用户全部的信息：名字。头像，按钮权限。角色、异步路由标记
          commit("SET_USERINFO", data);
          //获取服务器返回异步路由标记以后，开始算出这个用户全部的路由
          commit(
            "SET_USERALLROUTES",
            findUserAsyncRoute(cloneDeep(asyncRoutes), data.routes)
          );
          resolve(data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  },

  // user logout
  logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      logout(state.token)
        .then(() => {
          removeToken(); // must remove  token  first
          resetRouter();
          commit("RESET_STATE");
          resolve();
        })
        .catch((error) => {
          reject(error);
        });
    });
  },

  // remove token
  resetToken({ commit }) {
    return new Promise((resolve) => {
      removeToken(); // must remove  token  first
      commit("RESET_STATE");
      resolve();
    });
  },
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
};
